package screen;


import controller.DataStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Timer;
import javax.microedition.io.Connector;
import javax.microedition.io.ContentConnection;
import javax.microedition.io.HttpConnection;
import javax.microedition.io.StreamConnection;
import javax.microedition.lcdui.Image;

/**
 *
 * @author elio
 */
public class JXBMCRemote {
    /*      #define KEY_BUTTON_A                        256
    36	#define KEY_BUTTON_B                        257
    37	#define KEY_BUTTON_X                        258
    38	#define KEY_BUTTON_Y                        259
    39	#define KEY_BUTTON_BLACK                    260
    40	#define KEY_BUTTON_WHITE                    261
    41	#define KEY_BUTTON_LEFT_TRIGGER             262
    42	#define KEY_BUTTON_RIGHT_TRIGGER            263
    43
    44	#define KEY_BUTTON_LEFT_THUMB_STICK         264
    45	#define KEY_BUTTON_RIGHT_THUMB_STICK        265
    46
    47	#define KEY_BUTTON_RIGHT_THUMB_STICK_UP     266 // right thumb stick directions
    48	#define KEY_BUTTON_RIGHT_THUMB_STICK_DOWN   267 // for defining different actions per direction
    49	#define KEY_BUTTON_RIGHT_THUMB_STICK_LEFT   268
    50	#define KEY_BUTTON_RIGHT_THUMB_STICK_RIGHT  269
    51*/
    // Digital - don't change order

    private final String KEY_BUTTON_DPAD_UP = "270";
    private final String KEY_BUTTON_DPAD_DOWN = "271";
    private final String KEY_BUTTON_DPAD_LEFT = "272";
    private final String KEY_BUTTON_DPAD_RIGHT = "273";
    private final String KEY_BUTTON_START = "274";
    private final String KEY_BUTTON_BACK = "275";

    /*
    61	#define KEY_BUTTON_LEFT_THUMB_BUTTON        276
    62	#define KEY_BUTTON_RIGHT_THUMB_BUTTON       277
    63
    64	#define KEY_BUTTON_LEFT_ANALOG_TRIGGER      278
    65	#define KEY_BUTTON_RIGHT_ANALOG_TRIGGER     279
    66
    67	#define KEY_BUTTON_LEFT_THUMB_STICK_UP      280 // left thumb stick directions
    68	#define KEY_BUTTON_LEFT_THUMB_STICK_DOWN    281 // for defining different actions per direction
    69	#define KEY_BUTTON_LEFT_THUMB_STICK_LEFT    282
    70	#define KEY_BUTTON_LEFT_THUMB_STICK_RIGHT   283
    71
    72	#define KEY_VMOUSE          0xEFFF
    73
    74	// 0xF000 -> 0xF200 is reserved for the keyboard; a keyboard press is either
    75	#define KEY_VKEY            0xF000 // a virtual key/functional key e.g. cursor left*/
    private final String KEY_ASCII_ENTER = "0xf00d";
    private final String KEY_ASCII_ESC   = "0xf01b";
    /*76	#define KEY_ASCII           0xF100 // a printable character in the range of TRUE ASCII (from 0 to 127) // FIXME make it clean and pure unicode! remove the need for KEY_ASCII
    76	#define KEY_ASCII           0xF100 // a printable character in the range of TRUE ASCII (from 0 to 127) // FIXME make it clean and pure unicode! remove the need for KEY_ASCII
    77	#define KEY_UNICODE         0xF200 // another printable character whose range is not included in this KEY code
    78
    79	#define KEY_INVALID         0xFFFF
    80
    81	// actions that we have defined...
    82	#define ACTION_NONE                    0*/
    private final String ACTION_MOVE_UP = "3";
    private final String ACTION_MOVE_DOWN = "4";
    private final String ACTIONPAGE_UP = "5";
    private final String ACTION_PAGE_DOWN = "6";
    private final String ACTION_SELECT_ITEM = "7";
    /*90	#define ACTION_HIGHLIGHT_ITEM          8
    91	#define ACTION_PARENT_DIR              9
    92	#define ACTION_PREVIOUS_MENU          10
    93	#define ACTION_SHOW_INFO              11
    94
    95	#define ACTION_PAUSE                  12
    96	#define ACTION_STOP                   13
    97	#define ACTION_NEXT_ITEM              14
    98	#define ACTION_PREV_ITEM              15
    99	#define ACTION_FORWARD                16 // Can be used to specify specific action in a window, Playback control is handled in ACTION_PLAYER_*
    100	#define ACTION_REWIND                 17 // Can be used to specify specific action in a window, Playback control is handled in ACTION_PLAYER_*
    101
    102	#define ACTION_SHOW_GUI               18 // toggle between GUI and movie or GUI and visualisation.
    103	#define ACTION_ASPECT_RATIO           19 // toggle quick-access zoom modes. Can b used in videoFullScreen.zml window id=2005
    104	#define ACTION_STEP_FORWARD           20 // seek +1% in the movie. Can b used in videoFullScreen.xml window id=2005
    105	#define ACTION_STEP_BACK              21 // seek -1% in the movie. Can b used in videoFullScreen.xml window id=2005
    106	#define ACTION_BIG_STEP_FORWARD       22 // seek +10% in the movie. Can b used in videoFullScreen.xml window id=2005
    107	#define ACTION_BIG_STEP_BACK          23 // seek -10% in the movie. Can b used in videoFullScreen.xml window id=2005
    108	#define ACTION_SHOW_OSD               24 // show/hide OSD. Can b used in videoFullScreen.xml window id=2005
    109	#define ACTION_SHOW_SUBTITLES         25 // turn subtitles on/off. Can b used in videoFullScreen.xml window id=2005
    110	#define ACTION_NEXT_SUBTITLE          26 // switch to next subtitle of movie. Can b used in videoFullScreen.xml window id=2005
    111	#define ACTION_SHOW_CODEC             27 // show information about file. Can b used in videoFullScreen.xml window id=2005 and in slideshow.xml window id=2007
    112	#define ACTION_NEXT_PICTURE           28 // show next picture of slideshow. Can b used in slideshow.xml window id=2007
    113	#define ACTION_PREV_PICTURE           29 // show previous picture of slideshow. Can b used in slideshow.xml window id=2007
    */
    private final static String ACTION_ZOOM_OUT = "30"; // zoom in picture during slideshow. Can b used in slideshow.xml window id=2007
    private final static String ACTION_ZOOM_IN  = "31"; // zoom out picture during slideshow. Can b used in slideshow.xml window id=2007
    /*
    116	#define ACTION_TOGGLE_SOURCE_DEST     32 // used to toggle between source view and destination view. Can be used in myfiles.xml window id=3
    117	#define ACTION_SHOW_PLAYLIST          33 // used to toggle between current view and playlist view. Can b used in all mymusic xml files
    118	#define ACTION_QUEUE_ITEM             34 // used to queue a item to the playlist. Can b used in all mymusic xml files
    119	#define ACTION_REMOVE_ITEM            35 // not used anymore
    120	#define ACTION_SHOW_FULLSCREEN        36 // not used anymore
    121	#define ACTION_ZOOM_LEVEL_NORMAL      37 // zoom 1x picture during slideshow. Can b used in slideshow.xml window id=2007
    122	#define ACTION_ZOOM_LEVEL_1           38 // zoom 2x picture during slideshow. Can b used in slideshow.xml window id=2007
    123	#define ACTION_ZOOM_LEVEL_2           39 // zoom 3x picture during slideshow. Can b used in slideshow.xml window id=2007
    124	#define ACTION_ZOOM_LEVEL_3           40 // zoom 4x picture during slideshow. Can b used in slideshow.xml window id=2007
    125	#define ACTION_ZOOM_LEVEL_4           41 // zoom 5x picture during slideshow. Can b used in slideshow.xml window id=2007
    126	#define ACTION_ZOOM_LEVEL_5           42 // zoom 6x picture during slideshow. Can b used in slideshow.xml window id=2007
    127	#define ACTION_ZOOM_LEVEL_6           43 // zoom 7x picture during slideshow. Can b used in slideshow.xml window id=2007
    128	#define ACTION_ZOOM_LEVEL_7           44 // zoom 8x picture during slideshow. Can b used in slideshow.xml window id=2007
    129	#define ACTION_ZOOM_LEVEL_8           45 // zoom 9x picture during slideshow. Can b used in slideshow.xml window id=2007
    130	#define ACTION_ZOOM_LEVEL_9           46 // zoom 10x picture during slideshow. Can b used in slideshow.xml window id=2007
    131
    132	#define ACTION_CALIBRATE_SWAP_ARROWS  47 // select next arrow. Can b used in: settingsScreenCalibration.xml windowid=11
    133	#define ACTION_CALIBRATE_RESET        48 // reset calibration to defaults. Can b used in: settingsScreenCalibration.xml windowid=11/settingsUICalibration.xml windowid=10
    134	#define ACTION_ANALOG_MOVE            49 // analog thumbstick move. Can b used in: slideshow.xml window id=2007/settingsScreenCalibration.xml windowid=11/settingsUICalibration.xml windowid=10
    135	#define ACTION_ROTATE_PICTURE         50 // rotate current picture during slideshow. Can b used in slideshow.xml window id=2007
    136	#define ACTION_CLOSE_DIALOG           51 // action for closing the dialog. Can b used in any dialog
    137	#define ACTION_SUBTITLE_DELAY_MIN     52 // Decrease subtitle/movie Delay.  Can b used in videoFullScreen.xml window id=2005
    138	#define ACTION_SUBTITLE_DELAY_PLUS    53 // Increase subtitle/movie Delay.  Can b used in videoFullScreen.xml window id=2005
    139	#define ACTION_AUDIO_DELAY_MIN        54 // Increase avsync delay.  Can b used in videoFullScreen.xml window id=2005
    140	#define ACTION_AUDIO_DELAY_PLUS       55 // Decrease avsync delay.  Can b used in videoFullScreen.xml window id=2005
    141	#define ACTION_AUDIO_NEXT_LANGUAGE    56 // Select next language in movie.  Can b used in videoFullScreen.xml window id=2005
    142	#define ACTION_CHANGE_RESOLUTION      57 // switch 2 next resolution. Can b used during screen calibration settingsScreenCalibration.xml windowid=11
    143	#define ACTION_TOGGLE_WATCHED         58 // Toggle watched status (videos)
    144
    146	#define REMOTE_1                    59  // for example in videoFullScreen.xml window id=2005 you can
    147	#define REMOTE_2                    60  // enter time (mmss) to jump to particular point in the movie
    148	#define REMOTE_3                    61
    149	#define REMOTE_4                    62  // with spincontrols you can enter 3digit number to quickly set
    150	#define REMOTE_5                    63  // spincontrol to desired value
    151	#define REMOTE_6                    64
    152	#define REMOTE_7                    65
    153	#define REMOTE_8                    66
    154	#define REMOTE_9                    67
    155
    156	#define ACTION_PLAY                 68  // Unused at the moment
    157	#define ACTION_OSD_SHOW_LEFT        69  // Move left in OSD. Can b used in videoFullScreen.xml window id=2005
    158	#define ACTION_OSD_SHOW_RIGHT       70  // Move right in OSD. Can b used in videoFullScreen.xml window id=2005
    159	#define ACTION_OSD_SHOW_UP          71  // Move up in OSD. Can b used in videoFullScreen.xml window id=2005
    160	#define ACTION_OSD_SHOW_DOWN        72  // Move down in OSD. Can b used in videoFullScreen.xml window id=2005
    161	#define ACTION_OSD_SHOW_SELECT      73  // toggle/select option in OSD. Can b used in videoFullScreen.xml window id=2005
    162	#define ACTION_OSD_SHOW_VALUE_PLUS  74  // increase value of current option in OSD. Can b used in videoFullScreen.xml window id=2005
    163	#define ACTION_OSD_SHOW_VALUE_MIN   75  // decrease value of current option in OSD. Can b used in videoFullScreen.xml window id=2005
    164	#define ACTION_SMALL_STEP_BACK      76  // jumps a few seconds back during playback of movie. Can b used in videoFullScreen.xml window id=2005
    165
    166	#define ACTION_PLAYER_FORWARD        77  // FF in current file played. global action, can be used anywhere
    167	#define ACTION_PLAYER_REWIND         78  // RW in current file played. global action, can be used anywhere
    168	#define ACTION_PLAYER_PLAY           79  // Play current song. Unpauses song and sets playspeed to 1x. global action, can be used anywhere
    169
    170	#define ACTION_DELETE_ITEM          80  // delete current selected item. Can be used in myfiles.xml window id=3 and in myvideoTitle.xml window id=25
    171	#define ACTION_COPY_ITEM            81  // copy current selected item. Can be used in myfiles.xml window id=3
    172	#define ACTION_MOVE_ITEM            82  // move current selected item. Can be used in myfiles.xml window id=3
    173	#define ACTION_SHOW_MPLAYER_OSD     83  // toggles mplayers OSD. Can be used in videofullscreen.xml window id=2005
    174	#define ACTION_OSD_HIDESUBMENU      84  // removes an OSD sub menu. Can be used in videoOSD.xml window id=2901
    175	#define ACTION_TAKE_SCREENSHOT      85  // take a screenshot
    176	#define ACTION_POWERDOWN            86  // restart
    177	#define ACTION_RENAME_ITEM          87  // rename item
    178
     */
    private final String ACTION_VOLUME_UP = "88";
    private final String ACTION_VOLUME_DOWN = "89";
    private final String ACTION_MUTE = "91";
    /*182
    183	#define ACTION_MOUSE                90
    184
    185	#define ACTION_MOUSE_CLICK            100
    186	#define ACTION_MOUSE_LEFT_CLICK       100
    187	#define ACTION_MOUSE_RIGHT_CLICK      101
    188	#define ACTION_MOUSE_MIDDLE_CLICK     102
    189	#define ACTION_MOUSE_XBUTTON1_CLICK   103
    190	#define ACTION_MOUSE_XBUTTON2_CLICK   104
    191
    192	#define ACTION_MOUSE_DOUBLE_CLICK           105
    193	#define ACTION_MOUSE_LEFT_DOUBLE_CLICK      105
    194	#define ACTION_MOUSE_RIGHT_DOUBLE_CLICK     106
    195	#define ACTION_MOUSE_MIDDLE_DOUBLE_CLICK    107
    196	#define ACTION_MOUSE_XBUTTON1_DOUBLE_CLICK  108
    197	#define ACTION_MOUSE_XBUTTON2_DOUBLE_CLICK  109
    198
    199	#define ACTION_BACKSPACE          110
    200	#define ACTION_SCROLL_UP          111
    201	#define ACTION_SCROLL_DOWN        112
    202	#define ACTION_ANALOG_FORWARD     113
    203	#define ACTION_ANALOG_REWIND      114
    204
    205	#define ACTION_MOVE_ITEM_UP       115  // move item up in playlist
    206	#define ACTION_MOVE_ITEM_DOWN     116  // move item down in playlist
    207	#define ACTION_CONTEXT_MENU       117  // pops up the context menu
    208
    209
    210	// stuff for virtual keyboard shortcuts
    211	#define ACTION_SHIFT              118
    212	#define ACTION_SYMBOLS            119
    213	#define ACTION_CURSOR_LEFT        120
    214	#define ACTION_CURSOR_RIGHT       121
    215
    216	#define ACTION_BUILT_IN_FUNCTION  122
    217
    218	#define ACTION_SHOW_OSD_TIME      123 // displays current time, can be used in videoFullScreen.xml window id=2005
    219	#define ACTION_ANALOG_SEEK_FORWARD  124 // seeks forward, and displays the seek bar.
    220	#define ACTION_ANALOG_SEEK_BACK     125 // seeks backward, and displays the seek bar.
    221
    222	#define ACTION_VIS_PRESET_SHOW        126
    223	#define ACTION_VIS_PRESET_LIST        127
    224	#define ACTION_VIS_PRESET_NEXT        128
    225	#define ACTION_VIS_PRESET_PREV        129
    226	#define ACTION_VIS_PRESET_LOCK        130
    227	#define ACTION_VIS_PRESET_RANDOM      131
    228	#define ACTION_VIS_RATE_PRESET_PLUS   132
    229	#define ACTION_VIS_RATE_PRESET_MINUS  133
    230
    231	#define ACTION_SHOW_VIDEOMENU         134
    232	#define ACTION_ENTER                  135
    233
    234	#define ACTION_INCREASE_RATING        136
    235	#define ACTION_DECREASE_RATING        137
    236
    237	#define ACTION_NEXT_SCENE             138 // switch to next scene/cutpoint in movie
    238	#define ACTION_PREV_SCENE             139 // switch to previous scene/cutpoint in movie
    239
    240	#define ACTION_NEXT_LETTER            140 // jump through a list or container by letter
    241	#define ACTION_PREV_LETTER            141
    242
    243	#define ACTION_JUMP_SMS2              142 // jump direct to a particular letter using SMS-style input
    244	#define ACTION_JUMP_SMS3              143
    245	#define ACTION_JUMP_SMS4              144
    246	#define ACTION_JUMP_SMS5              145
    247	#define ACTION_JUMP_SMS6              146
    248	#define ACTION_JUMP_SMS7              147
    249	#define ACTION_JUMP_SMS8              148
    250	#define ACTION_JUMP_SMS9              149
    251
    252	#define ACTION_FILTER_CLEAR           150
    253	#define ACTION_FILTER_SMS2            151
    254	#define ACTION_FILTER_SMS3            152
    255	#define ACTION_FILTER_SMS4            153
    256	#define ACTION_FILTER_SMS5            154
    257	#define ACTION_FILTER_SMS6            155
    258	#define ACTION_FILTER_SMS7            156
    259	#define ACTION_FILTER_SMS8            157
    260	#define ACTION_FILTER_SMS9            158
    261
    262	#define ACTION_TOGGLE_FULLSCREEN      199 // switch 2 desktop resolution
    263
    264	// Window ID defines to make the code a bit more readable
    265	#define WINDOW_INVALID                     9999*/
    private final static int WINDOW_HOME     = 10000;
    private final static int WINDOW_PROGRAMS = 10001;
    private final static int WINDOW_PICTURES = 10002;
    private final static int WINDOW_FILES              = 10003;
    private final static int WINDOW_SETTINGS_MENU      = 10004;
    private final static int WINDOW_MUSIC              = 10005; // virtual window to return the music start window.
    private final static int WINDOW_VIDEOS             = 10006;
    private final static int WINDOW_SYSTEM_INFORMATION = 10007;
    private final static int WINDOW_TEST_PATTERN               = 10008;
    private final static int WINDOW_SCREEN_CALIBRATION         = 10011;

    private final static int WINDOW_SETTINGS_MYPICTURES        = 10012;
    private final static int WINDOW_SETTINGS_MYPROGRAMS        = 10013;
    private final static int WINDOW_SETTINGS_MYWEATHER         = 10014;
    private final static int WINDOW_SETTINGS_MYMUSIC           = 10015;
    private final static int WINDOW_SETTINGS_SYSTEM            = 10016;
    private final static int WINDOW_SETTINGS_MYVIDEOS          = 10017;
    private final static int WINDOW_SETTINGS_NETWORK           = 10018;
    private final static int WINDOW_SETTINGS_APPEARANCE        = 10019;

    private final static int WINDOW_SCRIPTS                    = 10020;
    private final static int WINDOW_VIDEO_GENRE                = 10021;
    private final static int WINDOW_VIDEO_ACTOR                = 10022;
    private final static int WINDOW_VIDEO_YEAR                 = 10023;
    private final static int WINDOW_VIDEO_FILES                = 10024;
    private final static int WINDOW_VIDEO_NAV                  = 10025;
    private final static int WINDOW_VIDEO_PLAYLIST             = 10028;

    private final static int WINDOW_LOGIN_SCREEN               = 10029;
    private final static int WINDOW_SETTINGS_PROFILES          = 10034;

    private final static int WINDOW_DIALOG_YES_NO              = 10100;
    private final static int WINDOW_DIALOG_PROGRESS            = 10101;
    private final static int WINDOW_DIALOG_KEYBOARD            = 10103;
    private final static int WINDOW_DIALOG_VOLUME_BAR          = 10104;
    private final static int WINDOW_DIALOG_SUB_MENU            = 10105;
    private final static int WINDOW_DIALOG_CONTEXT_MENU        = 10106;
    private final static int WINDOW_DIALOG_KAI_TOAST           = 10107;
    private final static int WINDOW_DIALOG_NUMERIC             = 10109;
    private final static int WINDOW_DIALOG_GAMEPAD             = 10110;
    private final static int WINDOW_DIALOG_BUTTON_MENU         = 10111;
    private final static int WINDOW_DIALOG_MUSIC_SCAN          = 10112;
    private final static int WINDOW_DIALOG_MUTE_BUG            = 10113;
    private final static int WINDOW_DIALOG_PLAYER_CONTROLS     = 10114;
    private final static int WINDOW_DIALOG_SEEK_BAR            = 10115;
    private final static int WINDOW_DIALOG_MUSIC_OSD           = 10120;
    private final static int WINDOW_DIALOG_VIS_SETTINGS        = 10121;
    private final static int WINDOW_DIALOG_VIS_PRESET_LIST     = 10122;
    private final static int WINDOW_DIALOG_VIDEO_OSD_SETTINGS  = 10123;
    private final static int WINDOW_DIALOG_AUDIO_OSD_SETTINGS  = 10124;
    private final static int WINDOW_DIALOG_VIDEO_BOOKMARKS     = 10125;
    private final static int WINDOW_DIALOG_FILE_BROWSER        = 10126;
    private final static int WINDOW_DIALOG_NETWORK_SETUP       = 10128;
    private final static int WINDOW_DIALOG_MEDIA_SOURCE        = 10129;
    private final static int WINDOW_DIALOG_PROFILE_SETTINGS    = 10130;
    private final static int WINDOW_DIALOG_LOCK_SETTINGS       = 10131;
    private final static int WINDOW_DIALOG_CONTENT_SETTINGS    = 10132;
    private final static int WINDOW_DIALOG_VIDEO_SCAN          = 10133;
    private final static int WINDOW_DIALOG_FAVOURITES          = 10134;
    private final static int WINDOW_DIALOG_SONG_INFO           = 10135;
    private final static int WINDOW_DIALOG_SMART_PLAYLIST_EDITOR = 10136;
    private final static int WINDOW_DIALOG_SMART_PLAYLIST_RULE   = 10137;
    private final static int WINDOW_DIALOG_BUSY                = 10138;
    private final static int WINDOW_DIALOG_PICTURE_INFO        = 10139;
    private final static int WINDOW_DIALOG_PLUGIN_SETTINGS     = 10140;
    private final static int WINDOW_DIALOG_ACCESS_POINTS       = 10141;
    private final static int WINDOW_DIALOG_FULLSCREEN_INFO     = 10142;
    
    private final static int WINDOW_MUSIC_PLAYLIST             = 10500;
    private final static int WINDOW_MUSIC_FILES                = 10501;
    private final static int WINDOW_MUSIC_NAV                  = 10502;
    private final static int WINDOW_MUSIC_PLAYLIST_EDITOR      = 10503;

    private final static int WINDOW_DIALOG_SELECT              = 12000;
    private final static int WINDOW_MUSIC_INFO                 = 12001;
    private final static int WINDOW_DIALOG_OK                  = 12002;
    private final static int WINDOW_VIDEO_INFO                 = 12003;
    private final static int WINDOW_SCRIPTS_INFO               = 12004;
    private final static int WINDOW_FULLSCREEN_VIDEO           = 12005;
    private final static int WINDOW_VISUALISATION              = 12006;
    private final static int WINDOW_SLIDESHOW                  = 12007;
    private final static int WINDOW_DIALOG_FILESTACKING        = 12008;
    private final static int WINDOW_WEATHER                    = 12600;
    private final static int WINDOW_SCREENSAVER                = 12900;
    private final static int WINDOW_OSD                        = 12901;
    
    private final static int WINDOW_VIDEO_MENU                 = 12902;
    private final static int WINDOW_MUSIC_OVERLAY              = 12903;
    private final static int WINDOW_VIDEO_OVERLAY              = 12904;

    private final static int WINDOW_STARTUP                    = 12999; // for startup animations
    
    private final static int WINDOW_PYTHON_START               = 13000;
    private final static int WINDOW_PYTHON_END                 = 13099;
    /*
    private final static int ICON_TYPE_NONE          101
    private final static int ICON_TYPE_PROGRAMS      102
    private final static int ICON_TYPE_MUSIC         103
    private final static int ICON_TYPE_PICTURES      104
    private final static int ICON_TYPE_VIDEOS        105
    private final static int ICON_TYPE_FILES         106
    private final static int ICON_TYPE_WEATHER       107
    private final static int ICON_TYPE_SETTINGS      109*/
    private String xbmcWebAddress;
    private Integer screenHeight;
    private Integer screenWidth;

    private String createXmbcCmdUrl() {
        return "http://" + xbmcWebAddress + "/xbmcCmds/xbmcHttp?command=";
    }

    public JXBMCRemote() {
    }

    public void init(String webserverAddrVal, String screenHeightVal, String screenWidthVal) {

        try {
            xbmcWebAddress = webserverAddrVal;
            screenHeight = Integer.valueOf(screenHeightVal);
            screenWidth = Integer.valueOf(screenWidthVal);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }

    }

    private long sendHttpRequest(String url, DataStream ds) {
        long responseLen = -1;
        HttpConnection hc = null;
//        System.err.println("cmd:"+url);
        try {
            hc = (HttpConnection) Connector.open(url);
            if (hc.getResponseCode() == HttpConnection.HTTP_OK) {
                responseLen = hc.getLength();
                if(ds!=null) {
                    ds.inputStream = hc.openInputStream();
                }
            }
            hc.close();
        } catch(Throwable ex) {
            ex.printStackTrace();
        } finally {
            try {
                if(hc!=null) hc.close();
            } catch(Throwable ex) {}
        }
        return responseLen;
    }

    private void sendCmd(String keyPadVal) throws IOException {
        String url = this.createXmbcCmdUrl() + "SendKey(" + keyPadVal + ")";
        this.sendHttpRequest(url, null);
        return;
    }

    private int getVolume() throws IOException {
        String url = this.createXmbcCmdUrl() + "GetVolume()";
        DataStream ds = new DataStream();
        this.sendHttpRequest(url, ds);

        StringBuffer buffer = new StringBuffer();
        StringBuffer volumeStr = new StringBuffer();
        int ch;
        boolean startNumber = false;
        while ((ch = ds.inputStream.read()) != -1) {
            if (ch != '\n') {
                if (buffer.toString().endsWith("<li>")) {
                    startNumber = true;
                } else if (buffer.toString().endsWith("</")) {
                    volumeStr.delete(volumeStr.length() - 2, volumeStr.length());
                    break;
                }
                if (startNumber) {
                    volumeStr.append((char) ch);
                }
                buffer.append((char) ch);
            }
        }
        ds.close();
        return Integer.parseInt(volumeStr.toString());
    }

    public int getGuiStatus() throws IOException {
        String url = this.createXmbcCmdUrl() + "GetGuiStatus()";
        DataStream ds = new DataStream();
        this.sendHttpRequest(url, ds);

        StringBuffer buffer = new StringBuffer();
        StringBuffer windowsIDStr = new StringBuffer();
        System.err.println(url);
        int ch;
        boolean startNumber = false;
        while ((ch = ds.inputStream.read()) != -1) {
            if (ch != '\n') {
                if (buffer.toString().endsWith("ActiveWindow:")) {
                    startNumber = true;
                }
                if (startNumber) {
                    windowsIDStr.append((char) ch);
                }
                buffer.append((char) ch);
            } else if(startNumber) {
                break;
            }
        }
        ds.close();
        return Integer.parseInt(windowsIDStr.toString());
    }

    private void setVolume(int volume) throws IOException {
        String url = this.createXmbcCmdUrl() + "SetVolume(" + Integer.toString(volume) + ")";
        this.sendHttpRequest(url, null);
    }

    public void takeSnapshot() throws IOException {
        String url = this.createXmbcCmdUrl() + "takescreenshot(special://xbmc/web/screen.jpg;true;90;"
                + screenHeight + ";"
                + screenWidth + ";90)";
        this.sendHttpRequest(url, null);
    }

    
    public Image refreshScreen() throws IOException {
        this.takeSnapshot();
        String url = "http://" + xbmcWebAddress + "/screen.jpg";
        DataStream ds = new DataStream();
        long respLen = this.sendHttpRequest(url, ds);

        Image img = null;
        try {
            if (respLen != -1) {
                // Create a byte array that size
                byte[] data = new byte[(int)respLen];
                // Read in the file
                ds.inputStream.read(data);
                // Create an image from the raw data
                img = Image.createImage(data, 0, (int)respLen);
            } else {
                ByteArrayOutputStream bStrm = new ByteArrayOutputStream();
                int ch;
                while ((ch = ds.inputStream.read()) != -1) {
                    bStrm.write(ch);
                }
                // Create an image from the raw data
                img = Image.createImage(bStrm.toByteArray(), 0, bStrm.toByteArray().length);
                bStrm.close();
            }
        } catch (Exception e) {
            System.out.println("IO Exception+" + e);
            e.printStackTrace();
        } finally {
            ds.close();
        }
        return img;
    }

    public void keyUp() throws IOException {
        this.sendCmd(this.KEY_BUTTON_DPAD_UP);
    }

    public void keyDown() throws IOException {
        this.sendCmd(this.KEY_BUTTON_DPAD_DOWN);
    }

    public void keyLeft() throws IOException {
        this.sendCmd(this.KEY_BUTTON_DPAD_LEFT);
    }

    public void keyRight() throws IOException {
        this.sendCmd(this.KEY_BUTTON_DPAD_RIGHT);
    }

    public void keySelect() throws IOException {
        this.sendCmd(this.KEY_ASCII_ENTER);
    }

    public void keyEsc() throws IOException {
        this.sendCmd(this.KEY_ASCII_ESC);
    }

    public void keyVolMute() throws IOException {
        this.setVolume(0);
    }

    public void keyVolUp() throws IOException {
        int volume = this.getVolume();
        this.setVolume(volume - 10);
    }

    public void keyVolDown() throws IOException {
        int volume = this.getVolume();
        this.setVolume(volume + 10);
    }

    public void keyChar(char c) throws IOException {
        this.sendCmd("0xf0"+Integer.toHexString((int)c));
    }

    public void shutDown() throws IOException {
        String url = this.createXmbcCmdUrl() + "Shutdown()";
        this.sendHttpRequest(url, null);
    }

    public void rotate() throws IOException {
        String url = this.createXmbcCmdUrl() + "Rotate()";
        this.sendHttpRequest(url, null);
    }

    public void zoom(int magnitude) throws IOException {
        String url = this.createXmbcCmdUrl() + "Zoom("+Integer.toString(magnitude)+")";
        this.sendHttpRequest(url, null);
    }

    public void move(int posX, int posY) throws IOException {
        String url = this.createXmbcCmdUrl() + "Move("+ Integer.toString(posX)+";"
                                                      + Integer.toString(posY)+")";
        this.sendHttpRequest(url, null);
    }
}
